// 放一些不好归类的工具方法
import Cookie from "js-cookie";

/**
 * 获取token
 */
export function getToken(): string {
  return Cookie.get("token") || "";
}

/**
 * 设置token，过期时间两个小时
 * @param token
 * @param expires
 */
export function setToken(token: string, expires = 2 * 60 * 60 * 1000): void {
  Cookie.set("token", token, {
    expires: new Date(+new Date() + expires),
  });
}

/**
 * 删除token
 */
export function deleteToken(): void {
  Cookie.remove("token");
}

/**
 * 空函数
 */
// eslint-disable-next-line @typescript-eslint/no-empty-function
export function noop(): void {}
Object.freeze(noop);

/**
 * 键路径
 * @param obj
 * @param path
 */
export function parsePath(obj: any, path: string): any {
  const segments = path.split(".");
  for (let i = 0; i < segments.length; i++) {
    if (!obj) return;
    obj = obj[segments[i]];
  }
  return obj;
}

/**
 * 递归深拷贝
 * @param target
 */
export function deepClone(target: any): any {
  let result: any;
  if (typeof target === "object") {
    if (Array.isArray(target)) {
      result = [];
      for (const i in target) {
        result.push(deepClone(target[i]));
      }
    } else if (target === null) {
      result = null;
    } else if (target.constructor === RegExp) {
      result = target;
    } else {
      result = {};
      for (const i in target) {
        result[i] = deepClone(target[i]);
      }
    }
  } else {
    result = target;
  }
  return result;
}

/**
 * 将target中存在的属性合并，不存在的属性不合并
 * @param target
 * @param source
 */
export function cover(target: any, source: any): void {
  for (const key in source) {
    if (key in target) {
      target[key] = source[key];
    }
  }
}

/**
 * 生成uuid
 */
export function getUuid(): string {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) =>
    // @ts-ignore
    (c === "x" ? (Math.random() * 16) | 0 : "r&0x3" | "0x8").toString(16)
  );
}

/**
 * 定时器
 * @param time
 * @param getTimerId
 */
export function wait(time = 0, getTimerId?: (timer: number) => any): Promise<void> {
  return new Promise((resolve) => {
    const timer = setTimeout(resolve, time);
    getTimerId && getTimerId(timer);
  });
}

/**
 * 阻塞线程
 * @param time
 */
export function sleep(time = 0): void {
  // eslint-disable-next-line no-empty
  for (let t = Date.now(); Date.now() - t <= time; ) {}
}

/**
 * 新增一个微任务
 */
export function nextTick(): Promise<void> {
  return Promise.resolve();
}

/**
 * 深度搜索树状数据结构算法
 * @param list 树状结构数据源
 * @param nodeKeyName 子节点字段名称
 * @param callback 操作节点
 */
export function deepSearch<T>(
  list: T[],
  nodeKeyName: string,
  callback: (item: T, currentList: T[]) => void | "end"
): void {
  for (let i = 0; i < list.length; i++) {
    if (callback(list[i], list) === "end") return;
    if (list[i][nodeKeyName]) {
      deepSearch(list[i][nodeKeyName], nodeKeyName, callback);
    }
  }
}
